﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.IO;

namespace Cinser.Common.Silverlight.DT
{
    /*
     * 内存中数据的一个表，由ColumnCollection对象和RowCollection对象构成
     * 使用方法：
     *     与System.Data.DataTable使用方法相似
     *     
     * */
    public class DMPDataTable 
    {

        //构造
        public DMPDataTable()
        {
            Columns.SetTable(this);
        }


        #region 方法

        /// <summary>
        /// 序列化表，包括数据和结构
        /// </summary>
        /// <returns>返回序列数据</returns>
        public string SerializeTable()
        {
            string str = Rows.Count.ToString()+","+Columns.Count.ToString()+",";
            object[]buf=new object[2*Columns.Count];
            int n=0;
            foreach(DMPDataColumn column in Columns)
            {
                buf[n] = column.ColumnName;
                buf[n + 1] = column.DataType.ToString();
                n += 2;
            }
            //System.Xml.Serialization.
            XmlSerializer xml = new XmlSerializer(buf.GetType());
            MemoryStream ms = new MemoryStream();
            xml.Serialize(ms, buf);
            str += Convert.ToBase64String(ms.ToArray());
            str += ",";
            str += this.SerializeData();
            return str;
        }

        /// <summary>
        /// 序列化数据，不包括格式
        /// </summary>
        /// <returns>返回序列数据</returns>
        public string SerializeData()
        {
            int n = 0;
            object[]buf=new object[Rows.Count*Columns.Count];
            
            foreach (DMPDataRow r in Rows)
            {
                foreach (DMPDataColumn c in Columns)
                {
                    buf[n] = r[c];
                    n++;
                }
            }
            string str = "";
            XmlSerializer xml = new XmlSerializer(buf.GetType());
            MemoryStream ms = new MemoryStream();
            xml.Serialize(ms, buf);
            str = Convert.ToBase64String(ms.ToArray());
            return str;
        }


        /// <summary>
        /// 反序列化
        /// </summary>
        /// <returns>返回表</returns>
        public void DeserializeTable(string str)
        {
            string[]strbuf = str.Split(',');
            int rnum=0,cnum=0;
            rnum = Convert.ToInt32(strbuf[0]);
            cnum = Convert.ToInt32(strbuf[1]);
            object[]format=new object[2*cnum];
            XmlSerializer xml = new XmlSerializer(format.GetType());
            //json;
            MemoryStream ms = new MemoryStream(Convert.FromBase64String(strbuf[2]));
            format=(object[])xml.Deserialize(ms);
            int n = 0;
            this.Clear();
            for (int i = 0; i < cnum;i++)
            {
                DMPDataColumn column = new DMPDataColumn((string)format[n], System.Type.GetType((string)format[n + 1]));
                n += 2;
                Columns.Add(column);
            }
            for (int i = 0; i < rnum;i++)
            {
                DMPDataRow row = NewRow();
                this.Rows.Add(row);
            }
            this.DeserializeData(strbuf[3]);
        }


        /// <summary>
        /// 反序列化
        /// </summary>
        /// <returns>返回数据</returns>
        public void DeserializeData(string str)
        {
            object[]buf=new object[Rows.Count*Columns.Count];
            XmlSerializer xml=new XmlSerializer(buf.GetType());
            MemoryStream ms = new MemoryStream(Convert.FromBase64String(str));
            buf=(object[])xml.Deserialize(ms);
            int n = 0;
            foreach (DMPDataRow r in Rows)
            {
                foreach (DMPDataColumn c in Columns)
                {
                    r[c]=buf[n];
                    n++;
                }

            }
        } 



        //NewRow 新建一个符合该表结构的row并返回
        public DMPDataRow NewRow()
        {
            DMPDataRow row= new DMPDataRow(Columns);
            row.SetTable(this);
            return row;
        }

        /// <summary>
        /// 所有表中的所有行都被移除，格式被清除
        /// </summary>
        public void Clear()
        {
            Columns.Clear();
            Rows.Clear();
        }

        /// <summary>
        /// Clone 方法创建的新 DataTable 与原始 DataTable 具有相同的结构
        /// 新 DataTable 不包含任何 DataRows
        /// </summary>
        /// <returns>DataTable</returns>
        public virtual DMPDataTable Clone()
        {
            DMPDataTable table = new DMPDataTable();
            table.Columns = new DMPColumnCollection(this.Columns);
            table.Columns.SetTable(table);
            return table;
        }

        /// <summary>
        /// Copy方法创建的新 DataTable 与原始 DataTable 具有相同的结构。
        /// Copy 方法创建的新 DataTable 与原始表具有相同的 DataRows 集
        /// </summary>
        /// <returns>DataTable</returns>
        public DMPDataTable Copy()
        {
            DMPDataTable table = this.Clone();
            table.Rows = new DMPRowCollection();
            for (int i = 0; i < this.Rows.Count;i++ )
            {
                table.Rows.Add(new DMPDataRow(table.Columns));
            }
            for (int i = 0; i < table.Rows.Count;i++ )
            {
                for (int j=0;j<table.Columns.Count;j++)
                {
                    table.Rows[i][j]=this.Rows[i][j];
                }
            }          
            return table;
        }


        #endregion



        #region  属性
        /// <summary>
        /// 获取或设置 DataTable 的名称
        /// </summary>
        private string tableName;
        public string TableName
        {
            get
            {
                return tableName;
            }
            set
            {
                if (value!=null)
                {
                    tableName = value;
                }
            }
        }
        #endregion

        public DMPColumnCollection Columns = new DMPColumnCollection();
        public DMPRowCollection Rows = new DMPRowCollection();



    }
}
